package com.xiashitech.agent.utils;

import com.xiashitech.agent.dns.CustomDns;
import com.xiashitech.agent.instrumentation.log.XSLevel;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.util.Map;
import java.util.logging.Logger;

public class HttpUtil {
    private static final Logger logger = Logger.getLogger(HttpUtil.class.getName());

    public static String doGet(String url, Map<String,String> params) {
        return doGet(url,params,null,null,false);
    }

    public static String doGet(String url, Map<String,String> params, String contentType, Map<String, String> heads, boolean isHttps) {
        String response = "";
        HttpURLConnection httpURLConnection = null;
        try {
            if(isHttps) {
                url = "https://" + url;
            } else {
                url = "http://" + url;
            }
            url = CustomDns.getInstance().domainToIpUrl(url);
            // 拼接请求参数
            if (params != null && !params.isEmpty()) {
                url += "?";
                StringBuilder sb = new StringBuilder();
                for (Map.Entry<String, String> entry : params.entrySet()) {
                    try {
                        sb.append(entry.getKey()).append("=").append(URLEncoder.encode(entry.getValue(), Charset.defaultCharset().name())).append("&");
                    } catch (Throwable e) {
                        sb.append(entry.getKey()).append("=").append(entry.getValue()).append("&");
                    }
                }
                sb.delete(sb.length() - 1, sb.length());
                url += sb.toString();
            }
            // DIRTY CODE, JUST FOR DEV & POC TEMP DEBUG.
            if (System.getProperty("xs.mock", "fasle").equalsIgnoreCase("true")){
                return XSUtil.mockAgentServer(url);
            }
            URL requestUrl = new URL(url);
            httpURLConnection = (HttpURLConnection) requestUrl.openConnection();
            httpURLConnection.setDoOutput(false);
            httpURLConnection.setDoInput(true);
            httpURLConnection.setRequestMethod("GET");
            httpURLConnection.setUseCaches(true);
            httpURLConnection.setInstanceFollowRedirects(true);
            httpURLConnection.setConnectTimeout(2000);
            httpURLConnection.setReadTimeout(2000);
            if(contentType != null && !"".equals(contentType)) {
                httpURLConnection.setRequestProperty("Content-Type", contentType);
            }
            if (heads != null && !heads.isEmpty()) {
                for (Map.Entry<String, String> entry : heads.entrySet()) {
                    httpURLConnection.setRequestProperty(entry.getKey(),entry.getValue());
                }
            }
            httpURLConnection.connect();
            int code = httpURLConnection.getResponseCode();
            if (code >= 200 && code < 300) {
                InputStream is = httpURLConnection.getInputStream();
                ByteArrayOutputStream baos = new ByteArrayOutputStream();
                int context;
                while ((context = is.read()) != -1) {
                    baos.write(context);
                }
                response = baos.toString("UTF-8");
            }
        } catch (Throwable e) {
            logger.log(XSLevel.DEBUG, e.getMessage() + ", url:" + url);
        }finally {
            if (httpURLConnection != null){
                try {
                    httpURLConnection.disconnect();
                }catch (Throwable e){
                    logger.log(XSLevel.DEBUG, e.getMessage());
                }
            }
        }
        return response;
    }

    public static String doPost(String url) {
        return doPost(url,null,null,null,false);
    }

    public static String doPost(String url, String body, String contentType) {
        return doPost(url,body,contentType,null,false);
    }

    public static String doPost(String url, String body, String contentType, Map<String, String> heads, boolean isHttps) {
        String response = "";
        HttpURLConnection httpURLConnection = null;
        try {
            if(isHttps) {
                url = "https://" + url;
            } else {
                url = "http://" + url;
            }
            if (System.getProperty("xs.mock", "fasle").equalsIgnoreCase("true")){
                return XSUtil.mockAgentServer(url);
            }
            // DIRTY CODE, JUST FOR DEV & POC TEMP DEBUG.
            if (System.getProperty("xs.mock", "fasle").equalsIgnoreCase("true")){
                response = XSUtil.mockAgentServer(url);
                return response;
            }
            url = CustomDns.getInstance().domainToIpUrl(url);
            URL requestUrl = new URL(url);
            httpURLConnection = (HttpURLConnection)requestUrl.openConnection();
            httpURLConnection.setRequestMethod("POST");
            httpURLConnection.setConnectTimeout(2000);
            httpURLConnection.setReadTimeout(2000);
            httpURLConnection.setDoOutput(true);
            httpURLConnection.setDoInput(true);
            httpURLConnection.setUseCaches(false);
            httpURLConnection.setInstanceFollowRedirects(true);
            if(contentType != null && !"".equals(contentType)) {
                httpURLConnection.setRequestProperty("Content-Type", contentType);
            }
            if (heads != null && !heads.isEmpty()) {
                for (Map.Entry<String, String> entry : heads.entrySet()) {
                    httpURLConnection.setRequestProperty(entry.getKey(),entry.getValue());
                }
            }
            httpURLConnection.connect();
            if(body != null && !"".equals(body)) {
                OutputStream out = httpURLConnection.getOutputStream();
                out.write(body.getBytes("UTF-8"));
                out.flush();
                out.close();
            }
            int code = httpURLConnection.getResponseCode();
            if (code >= 200 && code < 300) {
                InputStream is = httpURLConnection.getInputStream();
                ByteArrayOutputStream baos = new ByteArrayOutputStream();
                int context;
                while ((context = is.read()) != -1) {
                    baos.write(context);
                }
                response = baos.toString("UTF-8");
            }
        } catch (Throwable e) {
            logger.log(XSLevel.DEBUG, e.getMessage()+ ", url:" + url);
        }finally {
            if (httpURLConnection != null){
                try {
                    httpURLConnection.disconnect();
                }catch (Throwable e){
                    logger.log(XSLevel.DEBUG, e.getMessage());
                }
            }
        }
        return response;
    }
}
